home *** CD-ROM | disk | FTP | other *** search
- ; KNOBS
- ; Andrew Forrest
- ; Started 6 January 1994
- ; $VER: Knobs.asm 1.0 (12.02.94)
-
- ; Assembled with DEVPAC 3.02
- nolist
-
- ; Starting from V36, the Amiga OS has several bit switches embedded in
- ; various control structures. Several programs allow the user to alter these
- ; settings, including my mouse-accelerator/swiss-army-knife program MyMouse.
- ; I didn't like having all of these switch options in MyMouse, especially
- ; since there were several other switches I could think of adding, so I have
- ; split these extra options off into a seperate program--KNOBS!
-
- include everything.i
-
- Execbase equ 4
-
- ;*»» Code entrypoint
- ;*»» Allocate global memory for variables
- MAIN: move.l Execbase,a6
- moveq #Globals_SIZEOF,d0
- move.l #MEMF_CLEAR,d1
- just AllocMem
- tst.l d0
- beq Unhappy
- move.l d0,a5
- move.l a6,execbase(a5) ; Cache local (fast?) copy of execbase
-
- ;*»» Open the DOS library
- lea dosname(pc),a1
- moveq #0,d0 ; Open any version
- just OpenLibrary
- move.l d0,dosbase(a5)
- beq Unhappy
-
- ;*»» Open the utility library
- moveq #msg_NoUtility,d7
- lea utilityname(pc),a1
- moveq #37,d0
- just OpenLibrary
- move.l d0,utilitybase(a5)
- beq Error
-
- moveq #msg_OldDos,d7
- move.l dosbase(a5),a6
- cmp.w #36,LIB_VERSION(a6) ; Need at least V36 DOS for
- blo Error ; command-line parsing
- lea Template(pc),a0
- move.l a0,d1
- lea Options(a5),a0
- move.l a0,d2
- moveq #0,d3
- moveq #msg_NoArgs,d7
- just ReadArgs
- move.l d0,RdArgs(a5)
- beq Error
-
- ;*»» Handle 'STAR' option.
- move.l WildStarOption(a5),d1
- beq.s .NoStar
- move.l dosbase(a5),a0
- move.l dl_Root(a0),a0 ; (a6==dosbase(a5))
- lea rn_Flags(a0),a0
- moveq #0,d0
- move.l d1,a1
- bsr StringBit
- .NoStar
-
- ;*»» Perform NoClick, if desired.
- ; (d2=charflag;d3=unit#;d4=^MsgPort;a2=argument;a3=^IORequest)
- move.l execbase(a5),a6
- move.l NoClickOption(a5),d0
- beq .NoNoClick
- move.l d0,a2
- ;*»» Create an IORequest structure
- just CreateMsgPort
- move.l d0,d4 ; MsgPort in d4
- beq .NoNoClick
- move.l d4,a0
- moveq #IOSTD_SIZE,d0
- just CreateIORequest
- tst.l d0
- beq.s .fail
- move.l d0,a3 ; IORequest in a3
- moveq #-1,d3
- .ClickLoop addq.l #1,d3 ; Count trackdisk units
- move.b (a2)+,d2 ; Get next character of flag string
- beq.s .endloop ; Quit on string null-terminator
- lea TrackName(pc),a0 ;device name
- move.l d3,d0 ;unit number
- lea (a3),a1 ;IO request
- moveq.l #0,d1 ;flags
- just OpenDevice
- tst.l d0
- bne.s .ClickLoop
- move.l IO_UNIT(a3),a0
- lea TDU_PUBFLAGS(a0),a0
- moveq #TDPB_NOCLICK,d0
- move.b d2,d1
- bsr CharBit
- lea (a3),a1
- just CloseDevice
- bra.s .ClickLoop
- .endloop lea (a3),a0
- just DeleteIORequest
- .fail move.l d4,a0
- just DeleteMsgPort
- .NoNoClick
-
- ;*»» Border-blanking option.
- tst.l BorderBlankOption(a5)
- beq.s .NoBBlank
- moveq #msg_BBlankGfx,d7
- lea gfxname(pc),a1
- moveq #39,d0
- syscall OpenLibrary
- move.l d0,graphicsbase(a5)
- beq Error
- move.l d0,a0
- lea gb_BP3Bits(a0),a0
- moveq #5,d0
- move.l BorderBlankOption(a5),a1
- bsr StringBit
- moveq #msg_BBlankInt,d7
- lea intname(pc),a1
- moveq #33,d0
- just OpenLibrary
- move.l d0,intuitionbase(a5)
- beq.s Error
- intcall RemakeDisplay
- .NoBBlank
-
- ;*»» Alert-timer option.
- move.l AlertTimerOption(a5),d0
- beq.s .NoAlertTimer
- moveq #msg_ATiOldExec,d7
- move.l d0,a0
- move.l (a0),d0
- move.l execbase(a5),a0
- cmp.w #39,LIB_VERSION(a0)
- blo.s Error
- move.l d0,LastAlert+3*4(a0)
- .NoAlertTimer
-
- Satisfied: moveq #RETURN_OK,d0 ; Assume a happy ending
- bra.s Deallocate
- Unhappy: moveq #RETURN_FAIL,d0 ; Or maybe not
-
- ; Jump to this routine with d0=Returncode
- Deallocate: push.l d0
- move.l a5,d0
- beq.s .nothing ; Global structure not even there
- tst.l dosbase(a5)
- beq.s .no_dos ; Got to check, since we're _calling_ dos
- move.l RdArgs(a5),d1
- doscall FreeArgs ; Does nothing if passed NULL
- .no_dos lea LibraryBases(a5),a2
- move.l execbase(a5),a6
- moveq #NumLibraries-1,d2
- .librryloop move.l (a2)+,a1
- just CloseLibrary ; Does nothing if passed NULL
- dbra d2,.librryloop
- lea (a5),a1
- moveq #Globals_SIZEOF,d0
- just FreeMem
- .nothing pop.l d0 ; Get RETURN_ code back and...
- rts ; Return to DOS
-
- ;***************************************************************************
- ;** Error conditions
-
- ; Branch to here on error condition with d7=errn
- Error: move.w ErrorTable(pc,d7.w),d7
- lea ErrorTable(pc,d7.w),a0
- bsr Message
- bra Unhappy
-
- errn set 0
- Err macro ; Message-tag
- dc.w _\1-ErrorTable ;The error-message-table-entry
- msg_\1 equ errn ; The identifier (offset) for that entry
- errn set errn+2 ; Next table offset
- endm
-
- ErrorTable: Err OldDos
- Err NoUtility
- Err NoArgs
- Err BBlankGfx
- Err BBlankInt
- Err ATiOldExec
-
- _OldDos dc.b "You need Release 2 of AmigaDOS to use this program.",0
- _NoUtility dc.b "Can't open utility.library V37.",0
- _NoArgs dc.b "Unable to read command-line arguments.",0
- _BBlankGfx dc.b "Can't open graphics.library V39 for the BORDERBLANK option.",0
- _BBlankInt dc.b "Can't open intuition.library for the BORDERBLANK option.",0
- _ATiOldExec dc.b "You need Release 3 to use the ALERTTIMER option.",0
-
- even
- ;***************************************************************************
- ;***************************************************************************
- ;** Useful routines
-
- ; Print out the name of the program, colon, null-term string and end-of-line.
- ; Takes a0=^string\0; a5=^Globals (with dosbase); Returns, Trashes nil;
- Message:
- pushm.l a0-a2/a6/d0-d4
- lea (a0),a2 ; Store stringpointer for safe-keeping
- doscall Output ; \ Get the output channel
- move.l d0,d4 ; / And store in d4
- move.l d4,d1
- lea ProgramName(pc),a0
- move.l a0,d2
- moveq #NameLength,d3
- just Write ; Write the header: "KNOBS: "
- move.l d4,d1
- move.l a2,d2
- moveq #-1,d3 ; Assume string of zero length
- .loop addq.l #1,d3 ; ...add one to length
- tst.b (a2)+ ; ...test for null
- bne.s .loop ; ...and exit loop when we get it
- just Write ; Write out this string
- move.l d4,d1
- lea CarriageReturn(pc),a0
- move.l a0,d2
- moveq #1,d3
- just Write ; Write out the Carriage-Return
- popm.l a0-a2/a6/d0-d4
- rts
- ProgramName: dc.b "KNOBS: "
- NameLength equ *-ProgramName
- CarriageReturn: dc.b 10
-
- ; Uses Bit to change a bit based on a string which contains "ON", "OFF" or
- ; "CHANGE"--any other string has no effect. Uses utility library to do a
- ; case-insensitive string comparison.
- ; Takes a0=^flags; d0=bit#; a1=^string; Returns, Trashes nothing.
- ; Uses a2=^search string; d2=loopcounter=[CHANGE,OFF,ON]; d3=str offset;
- StringBit: push.w d1
- pushm.l a0-a3/a6/d0/d2-d3
- move.l utilitybase(a5),a6
- lea (a1),a2 ; Store user string for safekeeping
- moveq #0,d3 ; Clear top of d3
- moveq #3,d2 ; Initialise loopcounter==codenumber
- .loop lea (a2),a0 ; String supplied by user
- move.b Table-1(pc,d2.w),d3 ; Look up offset from table
- lea Table(pc,d3.w),a1 ; Obtain string from offset
- just Stricmp ; Compare the two strings
- tst.l d0
- dbeq d2,.loop ; Loop until match or counter reaches -1
- .endloop move.b d2,d1
- popm.l a0-a3/a6/d0/d2-d3
- bsr.s Bit
- pop.w d1
- rts
- Table: dc.b On-Table,Off-Table,Change-Table
- On dc.b "ON",0
- Off dc.b "OFF",0
- Change dc.b "CHANGE",0
- even
-
- ; Changes a bit based on a single character, d1, which is `1' (SET), `0'
- ; (CLEAR), `*' (CHANGE) or `-' (IGNORE).
- ; Takes a0=^flags; d0=bit#; d1.b=character; Trashes, returns nothing.
- CharBit: pushm.l a1/d2
- lea CharTable(pc),a1
- moveq #3,d2
- .loop cmp.b (a1)+,d1
- dbeq d2,.loop ; Keep looping til char=d1 or count=-1
- .endloop move.b d2,d1
- bsr.s Bit
- popm.l a1/d2
- rts
- CharTable: dc.b "*01-"
-
- ; (Possibly) changes a bit in a memory location based on whether d1
- ; is BITSET=1, BITCLEAR=2, BITCHANGE=3 or BITIGNORE=anything else.
- ; Takes a0=^flags; d0=bit#; d1.b=action; Returns & trashes nothing.
- Bit: push.w d1
- subq.b #1,d1
- bne.s .noset ; IF d1==BITSET THEN
- .set bset d0,(a0) ; set
- bra.s .end ; ELSE
- .noset subq.b #1,d1
- bne.s .noclear ; IF d1==BITCLEAR THEN
- .clear bclr d0,(a0) ; clear
- bra.s .end ; ELSE
- .noclear subq.b #1,d1
- bne.s .end ; IF d1==BITCHANGE THEN
- .change bchg d0,(a0) ; change
- .end pop.w d1 ; ENDIF
- rts
-
-
- ;***************************************************************************
- ;** Static data
- dc.b "$VER: Knobs 1.0 (06.02.94)"
-
- dosname dc.b "dos.library",0
- gfxname dc.b "graphics.library",0
- intname dc.b "intuition.library",0
- utilityname dc.b "utility.library",0
-
- TrackName: dc.b "trackdisk.device",0
-
- ;***************************************************************************
-
- ; Structure of global data area
- STRUCTURE Globals,0
-
- APTR execbase
- LABEL LibraryBases
- APTR dosbase
- APTR graphicsbase
- APTR intuitionbase
- APTR utilitybase
- LABEL EndLibs
- NumLibraries equ (EndLibs-LibraryBases)/4
-
- APTR RdArgs
-
- LABEL Options
- LONG AlertTimerOption
- LONG BorderBlankOption
- LONG NoClickOption
- LONG WildStarOption
- LABEL Globals_SIZEOF
-
- Template: dc.b "ALERTTIMER/K/N,"
- dc.b "BBLANK=BORDERBLANK/K,"
- dc.b "NOCLICK=NODISKCLICK/K,"
- dc.b "STAR=WILDSTAR/K"
- dc.b 0
-
-